package com.plugin.storage.aliyun;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.google.common.base.Strings;
import com.plugin.storage.base.AuthToken;
import com.plugin.storage.base.SdkCache;
import com.plugin.storage.base.SdkContext;
import com.plugin.storage.base.StorageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Instant;

public class AliyunSTS {

    private static final Logger LOGGER = LoggerFactory.getLogger(AliyunSTS.class);

    public static AuthToken authToken(SdkContext sdkContext) {
        return authToken(sdkContext, null);
    }

    public static AuthToken authToken(SdkContext sdkContext, String policy) {
        AuthToken token = SdkCache.getToken(sdkContext.getRoleArn() + Strings.nullToEmpty(policy));
        if (token != null) {
            return token;
        }
        try {
            DefaultProfile.addEndpoint("", sdkContext.getRegion(), "Sts", sdkContext.getTokenEndpoint());
            IClientProfile profile = DefaultProfile.getProfile(sdkContext.getRegion(), sdkContext.getAccessKeyId(), sdkContext.getAccessKeySecret());
            IAcsClient client = new DefaultAcsClient(profile);
            AssumeRoleRequest request = new AssumeRoleRequest();
            request.setRoleArn(sdkContext.getRoleArn());
            request.setRoleSessionName(sdkContext.getRoleSessionName());
            AssumeRoleResponse response = client.getAcsResponse(request);
            return SdkCache.putToken(sdkContext.getRoleArn() + Strings.nullToEmpty(policy), toToken(response));
        } catch (ClientException e) {
            LOGGER.error(e.getErrMsg(), e);
            throw new StorageException("获取凭证失败:" + e.getMessage(), e);
        }
    }

    private static AuthToken toToken(AssumeRoleResponse response) {
        AuthToken token = new AuthToken();
        return token.setAccessKeyId(response.getCredentials().getAccessKeyId())
                .setAccessKeySecret(response.getCredentials().getAccessKeySecret())
                .setSecurityToken(response.getCredentials().getSecurityToken())
                .setExpiration(Instant.parse(response.getCredentials().getExpiration()).getEpochSecond() * 1000);
    }
}
